// Copyright (C) 1953-2023 NUDT
// Verilog module name - host_buffer_input   
// Version: V4.3.0.20230309
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         receive and process pkt from host.
//             - top module.
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module host_buffer_input
(
        i_clk                            ,
        i_rst_n                          ,
                                         
        iv_addr                          ,      
        iv_wdata                         ,     
        i_wr                         ,
        i_rd                         ,             
        o_wr                         ,
        ov_addr                      ,
        ov_rdata                     ,                                   
               
        i_data_wr                        ,
        iv_data                          ,
		  iv_ipv                           ,
        iv_inject_dbufid                 ,
        
        iv_pkt_bufid                     ,
        i_pkt_bufid_wr                   ,
        o_pkt_bufid_ack                  ,                                                          
                                         
        ov_pkt                         ,
        o_pkt_wr                        ,
        ov_pkt_bufadd                    ,
        i_pkt_ack                      ,
                                                                                 
        i_hardware_initial_finish        ,
        i_rc_rxenable        ,  
        i_st_rxenable        ,        
        
        iv_st_stream_state   ,
        o_st_inject_overflow_pulse,

        ov_desp       ,
        //ov_st_inject_dbufid,
        o_desp_wr     ,
             
        iv_free_bufid_num                ,
        iv_hpriority_be_threshold_value  ,
        iv_rc_threshold_value            ,
        iv_lpriority_be_threshold_value 
);
// I/O
// clk & rst
input                  i_clk                     ;
input                  i_rst_n                   ; 

input       [18:0]     iv_addr                   ;
input       [31:0]     iv_wdata                  ;
input                  i_wr                  ;
input                  i_rd                  ;

output                 o_wr                  ;
output      [18:0]     ov_addr               ;
output      [31:0]     ov_rdata              ;           
// send pkt data from gmii     
input       [8:0]      iv_data                  ;
input                  i_data_wr                ;
input       [2:0]      iv_ipv                  ;
input       [4:0]      iv_inject_dbufid        ;
// bufid input                                   
input      [8:0]       iv_pkt_bufid             ;
input                  i_pkt_bufid_wr           ;
output                 o_pkt_bufid_ack          ;
// pkt output                                    
output    [133:0]      ov_pkt                  ;
output                 o_pkt_wr                 ;
output    [15:0]       ov_pkt_bufadd             ;
input                  i_pkt_ack               ;

input                  i_hardware_initial_finish ;
input                  i_rc_rxenable                   ;
input                  i_st_rxenable                   ;
//threshold of discard
input      [8:0]       iv_free_bufid_num              ;
input      [8:0]       iv_hpriority_be_threshold_value;
input      [8:0]       iv_rc_threshold_value          ;
input      [8:0]       iv_lpriority_be_threshold_value;

input      [31:0]      iv_st_stream_state ;
output                 o_st_inject_overflow_pulse;

output     [16:0]      ov_desp      ; 
//output     [4:0]       ov_st_inject_dbufid; 
output                 o_desp_wr     ; 
/////////////////////////////////////////////////////////// 
wire                   w_pkt_wr_cra2ibi;
wire       [133:0]     wv_pkt_cra2ibi  ; 

wire                   w_pkt_bufid_wr_cra2ibi;
wire       [8:0]       wv_pkt_bufid_cra2ibi  ; 

wire       [8:0]       wv_data_som2tp           ;
wire                   w_data_wr_som2tp         ;
wire       [2:0]       wv_ipv_som2tp            ;
wire       [4:0]       wv_inject_dbufid_som2tp  ;

wire       [8:0]       wv_data_tp2das           ;
wire                   w_data_wr_tp2das         ;
wire       [2:0]       wv_ipv_tp2dp             ;
wire       [4:0]       wv_inject_dbufid_tp2dp   ;
wire                   w_desp_wr_tp2dp          ;

wire       [8:0]       wv_data_ine2som          ;
wire                   w_data_wr_ine2som        ;
wire       [4:0]       wv_inject_dbufid_ine2som ;
wire       [2:0]       wv_ipv_ine2som           ;

wire                   w_desp_wr_big2dem          ;
wire       [16:0]      wv_desp_big2dem            ;
//wire       [4:0]       wv_st_inject_dbufid_big2dem;

info_extract info_extract_inst(
        .i_clk                   (i_clk           ),
        .i_rst_n                 (i_rst_n         ),
                                  
        .iv_data                 (iv_data         ),
        .i_data_wr               (i_data_wr       ),
		  .iv_ipv                  (iv_ipv          ),
        .iv_inject_dbufid        (iv_inject_dbufid),
                                  
        .ov_data                 (wv_data_ine2som         ),
        .o_data_wr               (w_data_wr_ine2som       ),
        .ov_inject_dbufid        (wv_inject_dbufid_ine2som),
        .ov_ipv                  (wv_ipv_ine2som          ),
        .o_replication_flag      (),
        .o_ctag_flag             ()
);

st_overflow_monitor st_overflow_monitor_inst
(
       .i_clk                     (i_clk  ),
       .i_rst_n                   (i_rst_n),
        
       .iv_data                   (wv_data_ine2som         ),
       .i_data_wr                 (w_data_wr_ine2som       ),      
       .iv_inject_dbufid          (wv_inject_dbufid_ine2som),
       .iv_ipv                    (wv_ipv_ine2som          ),
        
       .iv_st_stream_state        (iv_st_stream_state      ),
       .o_pkt_cnt_pulse           (),
      
       .ov_data                   (wv_data_som2tp         ),
       .o_data_wr                 (w_data_wr_som2tp       ),
       .ov_ipv                    (wv_ipv_som2tp          ),       
       .ov_inject_dbufid          (wv_inject_dbufid_som2tp),   
        
       .o_st_overflow_error_pulse (o_st_inject_overflow_pulse)     
);

traffic_police traffic_police_inst
(
        .i_clk                           (i_clk  ),
        .i_rst_n                         (i_rst_n),
       
        .iv_data                         (wv_data_som2tp         ),
        .i_data_wr                       (w_data_wr_som2tp       ),
        .iv_ipv                          (wv_ipv_som2tp          ),       
        .iv_inject_dbufid                (wv_inject_dbufid_som2tp),
        
        .iv_free_bufid_num               (iv_free_bufid_num              ),
        .iv_hpriority_be_threshold_value (iv_hpriority_be_threshold_value),
        .iv_rc_threshold_value           (iv_rc_threshold_value          ),
        .iv_lpriority_be_threshold_value (iv_lpriority_be_threshold_value),
        .ov_pkt_discard_cnt              (                               ),
        
        .ov_data                         (wv_data_tp2das                 ),
        .o_data_wr                       (w_data_wr_tp2das               ),
        .ov_ipv                          (wv_ipv_tp2dp                   ),       
        .ov_inject_dbufid                (wv_inject_dbufid_tp2dp         ),
        .o_desp_wr                       (w_desp_wr_tp2dp                )
    );
    
bufid_get bufid_get_inst 
(
        .i_clk              (i_clk                  ),
        .i_rst_n            (i_rst_n                ),
       
        .iv_ipv             (wv_ipv_tp2dp           ),       
        .iv_inject_dbufid   (wv_inject_dbufid_tp2dp ),
        .i_desp_wr          (w_desp_wr_tp2dp        ),
       
        .i_pkt_bufid_wr     (i_pkt_bufid_wr         ),
        .iv_pkt_bufid       (iv_pkt_bufid           ),
        .o_pkt_bufid_ack    (o_pkt_bufid_ack        ),
    
        .o_pkt_bufid_wr     (w_pkt_bufid_wr_cra2ibi),
        .ov_pkt_bufid       (wv_pkt_bufid_cra2ibi  ),
        
        .o_desp_wr          (w_desp_wr_big2dem          ),
        .ov_desp            (wv_desp_big2dem            ) 
        //.ov_st_inject_dbufid(wv_st_inject_dbufid_big2dem)
    ); 

delay_management #(.delay_cycles(6'd40)) host_desp_delay_inst
(
        .i_clk                (i_clk              ),
        .i_rst_n              (i_rst_n            ),
                                                  
        .i_desp_wr            (w_desp_wr_big2dem          ),
        .iv_desp              (wv_desp_big2dem            ),
        //.iv_st_inject_dbufid  (wv_st_inject_dbufid_big2dem),
                                                  
        .o_desp_wr            (o_desp_wr          ),
        .ov_desp              (ov_desp            ) 
        //.ov_st_inject_dbufid  (ov_st_inject_dbufid)
    );
    
data_splice data_splice_inst
(
        .i_clk              (i_clk  ),
        .i_rst_n            (i_rst_n),
        .i_data_wr          (w_data_wr_tp2das ),
        .iv_data            (wv_data_tp2das   ),
        .o_pkt_wr           (w_pkt_wr_cra2ibi),
        .ov_pkt             (wv_pkt_cra2ibi  ),
                          
        .data_splice_state  ()
    );    
    

input_buffer_interface input_buffer_interface_inst
(
        .i_clk                       (i_clk  ),
        .i_rst_n                     (i_rst_n),
        .i_pkt_wr                    (w_pkt_wr_cra2ibi),
        .iv_pkt                      (wv_pkt_cra2ibi  ),
        .i_pkt_bufid_wr              (w_pkt_bufid_wr_cra2ibi),
        .iv_pkt_bufid                (wv_pkt_bufid_cra2ibi  ),
        .ov_pkt                      (ov_pkt     ),
        .o_pkt_wr                    (o_pkt_wr    ),
        .ov_pkt_bufadd               (ov_pkt_bufadd),
        .i_pkt_ack                   (i_pkt_ack  ),
        .o_pkt_write_finish(),
        .input_buf_interface_state   ()
    );
(*MARK_DEBUG="true"*) reg  [15:0]  rv_pkt_counter/*synthesis noprune*/;
(*MARK_DEBUG="true"*) reg  r_data_valid;
always @(posedge i_clk or negedge i_rst_n) begin
    if (!i_rst_n) begin
        rv_pkt_counter <= 16'b0;
		r_data_valid    <=  1'b0;
    end
    else begin
	    r_data_valid <= i_data_wr;
        if((!r_data_valid) && i_data_wr)begin
			rv_pkt_counter <= rv_pkt_counter + 1'b1;
        end
        else begin
            rv_pkt_counter <=  rv_pkt_counter;
        end		
	end	
end
endmodule